package com.shuijianbaozi.mediaplayer;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.support.v7.app.NotificationCompat;
import android.util.Log;
import android.widget.RemoteViews;

/**
 * Created by bodhixu on 2016/9/26.
 * 播放音乐的服务;都是四大控件,可以和最熟悉的activity做类比,app如果退出,则service也随着app弹出任务栈
 */
public class PlayService extends Service{

    private MediaPlayer player; //播放器

    //-----------------------通知相关---------------
    public static final int FLAG_PLAY_NOTIFICATION = 100;
    private RemoteViews playRemoteViews;
    private Notification playNotification;
    private NotificationManager playNotificationManager;

    @Override
    public void onCreate() {
        super.onCreate();
        initPlayer();
        initNotification();
    }

    //todo 2.0 初始化通知
    private void initNotification() {
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
        //设置自定义ui;todo 2.1 通知的界面布局和属性
        playRemoteViews = new RemoteViews(getPackageName(), R.layout.notification_play);
//         playRemoteViews.setOnClickPendingIntent(id, pendingintent); 用于按钮的点击事件
        builder.setContent(playRemoteViews);
        //设置属性
//        builder.setDefaults(Notification.DEFAULT_ALL);
        //设置点击的响应事件
        Intent intent = new Intent(this, MainActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); //单任务模式
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        builder.setContentIntent(pendingIntent);

        //todo 2.2 创建通知
        playNotification = builder.build();
        playNotification.icon = R.mipmap.ic_launcher;
        playNotification.flags |= Notification.FLAG_NO_CLEAR; //cancel按钮失效，通知不能取消

        //todo 2.3 创建通知管理;
        playNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    }

    // todo 1.0 初始化播放器
    /**
     * 初始化的步骤：
          第一步，创建一个播放器new MediaPlayer()。
          第二步，加载音频资源setDataSource()。;demo的音乐资源放在了raw本地文件中,启动页面可以这么处理,但是大部分是需要用网络的数据的
          第三步，准备就绪prepare()
      如果加载本地固定资源，可以把以上步骤合而为一//66
     */
    private void initPlayer() {
        player = MediaPlayer.create(this, R.raw.bobala);
        //设置当前歌曲是否循环播放
        player.setLooping(true);
        //拖动完成监听
        player.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {
            @Override
            public void onSeekComplete(MediaPlayer mediaPlayer) {
                //拖动完成，一般会使用到加载网络歌曲，解决延时卡顿的问题
            }
        });
        //歌曲播放完成的监听
        player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mediaPlayer) {
                Log.e("Tag", "-----------> onCompletion");
                //一般用于循环方式的设置
            }
        });
    }
//接收MainActivity 传递的intent
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        //todo 3.0 接收activity的指令
        int action = intent.getIntExtra(MyContstants.KEY_CONTROL, 0);
        switch (action) {
            case MyContstants.ACTION_PLAY: //播放
                player.start();
                new Thread(new UpdateRunnble()).start();//???开始为什么放在thread中?
                break;
            case MyContstants.ACTION_PAUSE: //暂停
                player.pause();
                break;
            case MyContstants.ACTION_SEEK: //拖动
                int progress = intent.getIntExtra(MyContstants.KEY_SEEK_PROGRESS, 0); //播放进度;百分制
                int duration = player.getDuration();//歌曲总时长，单位毫秒
                player.seekTo(duration * progress / 100); //拖动到指定位置，歌曲毫秒;;实际position
                break;
        }

        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        //释放资源
        player.stop(); //停止。
        // 停止和暂停的区别：暂停后歌曲资源依然在播放器上，重新播放直接调用start（）。而停止，则把歌曲资源从播放器上清除了，因此重新播放需要重新加载资源。
        player.release(); //释放资源
        player = null;//???为什么归置为null
        //取消通知
        playNotificationManager.cancel(FLAG_PLAY_NOTIFICATION);
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    //通知Activity刷新的任务 进度条每隔一秒刷新一次 activity的进度条和通知栏的进度条
    class UpdateRunnble implements Runnable{
        @Override
        public void run() {//每个1秒发送广播，通知Activity刷新画面
            while (player != null && player.isPlaying()){//在正在播放的时候
                //todo 3.1 Activity更新播放进度(自定义Broadcast发送当前播放进度)
                Intent intent = new Intent(MyContstants.ACTION_BROADCAST_PROGRESS);
                //获得当前进度;; 实际position/实际duration*100 是百分制进度
                int progress = player.getCurrentPosition() * 100 / player.getDuration();
                intent.putExtra(MyContstants.KEY_PLAY_PROGRESS, progress);

                sendBroadcast(intent); //----发送广播
                //todo 3.2 Notification 更新当前的播放进度
                //-----更新通知进度;可以直接通过id指定,不需要实例话ProgressBar控件?
                playRemoteViews.setProgressBar(R.id.pgb_play, 100, progress, false);
                //发送通知;更新通知的progressBar
                playNotificationManager.notify(FLAG_PLAY_NOTIFICATION, playNotification);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
